home *** CD-ROM | disk | FTP | other *** search
/ Packard Bell - Internet on a CD / internet on a cd.cdr / Internet / sites / Clementine_NASA / clemdsrc.hqx / pds.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-27  |  12.7 KB  |  492 lines

  1. /*  
  2.  *    THIS ROUTINE IS PART OF THE CLEMENTINE PDS FILE READER PROGRAM.
  3.  *    IT WAS WRITTEN BY ACT CORP. IN DIRECT SUPPORT TO THE 
  4.  *    CLEMENTINE (DSPSE) PROGRAM.
  5.  *
  6.  *    IF YOU FIND A PROBLEM OR MAKE ANY CHANGES TO THIS CODE PLEASE CONTACT
  7.  *    Dr. Erick Malaret at ACT Corp. 
  8.  *            tel: (703) 742-0294
  9.  *                 (703) 683-7431
  10.  *                       email:    nrlvax.nrl.navy.mil
  11.  *    
  12.  *
  13.  *    Changes were made for the Macintosh version.  These changes were
  14.  *    made by Tracie Sucharski at the USGS in Flagstaff and are marked with
  15.  *    a comment denoted as  " TS ".  Macintosh does not allow an application to
  16.  *    use printf.  A routine, "errmsg" was substituted which writes error 
  17.  *    messages to a window.
  18.  *    Changes to memory handling also had to be made to accomodate Macintosh.  These
  19.  *    changes are marked with comments of " DL ".
  20.  *
  21.  */
  22. #include <stdio.h>
  23. #include <math.h>
  24. #ifdef __TURBOC__
  25. #include <alloc.h>
  26. #else
  27. #include <stdlib.h>
  28. #endif
  29. #include <string.h>
  30. #include "jpeg_c.h"
  31. #include "pds.h"
  32.  
  33. #define READ_PARAM "rb"
  34. #define WRITE_PARAM "wb"
  35.  
  36. PDSINFO    pds;
  37. FILE    *qparm;
  38.  
  39. void init_qt(FILE *fptr);
  40. void readhufftbls(FILE *fptr);
  41. void pds_decomp(FILE *fptr,CHARH *p,long sizej,long sizei);
  42. #if defined(SUN) || defined(__STDC__) 
  43. void PClong2SUNlongVector(unsigned long invec[],int npts) ;
  44. void PCshort2SUNshortVector(unsigned short invec[],int npts) ;
  45. #endif
  46.  
  47. void errmsg();
  48. extern long int resnum;
  49. extern long int resnumq;
  50.  
  51.  
  52. PDSINFO *PDSR(char *fname, long *rows, long *cols)
  53. {
  54.     FILE    *fptr;
  55.     int     n;
  56.     int     j,i;
  57.     Handle  c;       /* DL */
  58.     CHARH   *b;      /* DL */
  59.     char    nstring[84],sdummy[80],buffer[10],low;
  60.     long    sizej;                  /* number of rows in the image */
  61.     long    sizei;                  /* number of columns in the image */
  62.     int     bitpix;                 /* bits per pixel */
  63.     int     record_bytes;
  64.     int     hist_rec,brw_rec,image_rec,ns,brwsize;
  65.     char    cval, *sptr, *ptr;
  66.     char    record_type[20];
  67.     char    errbuf[132];  /* TS */
  68.     int     COMPRESSED;
  69.     long    k,hdr_size;
  70.  
  71.     if( (fptr = fopen(fname,READ_PARAM)) == NULL){  /* open disk file */
  72.         sprintf(errbuf,"Can't open %s.\n",fname);  /* TS */
  73.         errmsg(errbuf,&resnumq);  /* TS */
  74.         return NULL;
  75.     }
  76.  
  77.     /* initialize some basic variables */
  78.     bitpix            =0;
  79.     sizej=sizei        =0;
  80.     pds.browse_nrows    =0;
  81.     pds.browse_ncols    =0;
  82.     pds.image_nrows        =0;
  83.     pds.image_ncols        =0;
  84.     hist_rec = brw_rec = image_rec = -1;
  85.  
  86.     /* read header */
  87.     do{
  88.         /* read next line of text */
  89.         for (n=0; (cval=fgetc(fptr)); n++) {
  90.             nstring[n]=cval;
  91.             if(cval=='\n') {
  92.                 if( (cval=fgetc(fptr)) != '\r') ungetc(cval,fptr);
  93.                 nstring[++n]='\0';
  94.                 break;
  95.             }
  96.         }
  97.  
  98.         /* find line's first non-space character */
  99.         for (ns=0; nstring[ns]==' ';ns++);
  100.         sptr = &nstring[ns];
  101.  
  102.         if (strncmp("^IMAGE_HISTOGRAM ",sptr,17)==0) {
  103.                     /*printf("image histogram found \n"); */ 
  104.             n=sscanf(nstring,"%s = %d", sdummy, &hist_rec);
  105.                         /*printf("hist_rec = %d\n",hist_rec);*/
  106.         }
  107.  
  108.         if (strncmp("^BROWSE_IMAGE ",sptr,14)==0) {
  109.             n=sscanf(nstring,"%s = %d", sdummy, &brw_rec);
  110.                     /*printf("brw_rec = %d\n",brw_rec);*/
  111.         }
  112.  
  113.         if (strncmp("^IMAGE ",sptr,7)==0) {
  114.             n=sscanf(nstring,"%s = %d", sdummy, &image_rec);
  115.         }
  116.  
  117.         if (strncmp("RECORD_TYPE",sptr,9)==0) {
  118.             n=sscanf(nstring,"%s = %s", sdummy, &record_type);
  119.         }
  120.  
  121.         if (strncmp("RECORD_BYTES",sptr,12)==0) {
  122.             n=sscanf(nstring,"%s = %d", sdummy, &record_bytes);
  123.         }
  124.  
  125.         if (strncmp("ENCODING_TYPE",sptr,13)==0) {
  126.             n=sscanf(nstring,"%s = %s", sdummy, buffer);
  127.             if ( strstr(buffer,"JPEG") )
  128.                 COMPRESSED = 1;
  129.             else
  130.                 COMPRESSED = 0;
  131.         }
  132.  
  133.         if (strncmp("LINES ",sptr,6)==0) {
  134.             n=sscanf(nstring,"%s = %ld", sdummy, &sizej);
  135.         }
  136.  
  137.         if (strncmp("LINE_SAMPLES",sptr,12)==0) {
  138.             n=sscanf(nstring,"%s = %ld", sdummy, &sizei);
  139.         }
  140.  
  141.         if (strncmp("SAMPLE_BITS",sptr,11)==0) {
  142.             n=sscanf(nstring,"%s = %d", sdummy, &bitpix);
  143.         }
  144.  
  145.         if (strncmp("END",sptr,3)==0) {
  146.             if ( *(sptr+3)=='\n' || *(sptr+3)==' ' || *(sptr+3)=='\r' ) {
  147.                 hdr_size = ftell(fptr);
  148.                 break;
  149.             }
  150.         }
  151.     } while(1);
  152.  
  153.     /**************   read histogram  ***************/
  154.     if ( hist_rec != -1 ) {
  155.         fseek(fptr,hist_rec-1,0);
  156.         pds.hist = (long *)malloc(256*sizeof(long));
  157.         if(pds.hist == NULL){
  158.                          errmsg(" histogram memory not allocated \n",&resnum);  /* TS */
  159.                 }
  160.         if ( pds.hist ){
  161.               fread(pds.hist,sizeof(long),256,fptr);
  162. #if defined(sun) || defined(__STDC__)
  163.               PClong2SUNlongVector((unsigned long*)pds.hist,256);
  164. #endif
  165.                     /*printf("pds.hist = %x\n",pds.hist);*/ 
  166.                 }
  167.     }
  168.  
  169.     /**************   read browse image **********/
  170.         if ( brw_rec != -1 ) {
  171.             pds.browse_ncols    = sizei/8;
  172.             pds.browse_nrows    = sizej/8;
  173.             fseek(fptr,brw_rec-1,0);
  174.             brwsize = (sizej/8) * (sizei/8);
  175.         /*    pds.brw_imag = (unsigned char *)malloc(brwsize);  */
  176.             pds.brw_imag = NewHandle(brwsize);   /* DL */
  177.             if ( pds.brw_imag )
  178.                 MoveHHi(pds.brw_imag);
  179.                 HLock(pds.brw_imag);    /* DL */
  180.                 fread((unsigned char *)*(pds.brw_imag),sizeof(char),brwsize,fptr); /* DL */
  181.           /*      fread(pds.brw_imag,sizeof(char),brwsize,fptr);  */
  182.                 HUnlock(pds.brw_imag); /* DL */
  183.         }
  184.  
  185.     /*************   read image data ***************/
  186.     if (strncmp(record_type,"UNDEFINED",9)==0) {
  187.         record_bytes=1;
  188.         fseek(fptr,(image_rec-1),0);
  189.     } else {
  190.         fseek(fptr,(image_rec-1)*record_bytes,0);
  191.     }
  192.  
  193.     switch (bitpix) {
  194.     case 8:
  195. #ifdef __TURBOC__
  196.         c = NewHandle(sizej*sizei);   /* DL */
  197. #else
  198.         c = NewHandle(sizej*sizei);   /* DL */
  199. #endif
  200.         if ( c == NULL ) {
  201.             errmsg("Can't allocate memory for image array.\n",&resnumq);  /* TS */
  202.             fclose(fptr);
  203.             return NULL;
  204.         }
  205.  
  206.         if ( COMPRESSED ) {
  207.             qparm = fopen("paramtrs.dat","w");
  208.             init_qt(fptr);
  209.             readhufftbls(fptr);
  210.             MoveHHi(c);     /* DL */
  211.             HLock(c);       /* DL */
  212.             pds_decomp(fptr,(CHARH *)*c,sizej,sizei);  /* DL */
  213.             HUnlock(c);     /* DL */
  214.             fclose(qparm);
  215.         } else {
  216.                     
  217.             for (j=0, k=0; j<sizej ;j++) {
  218.                 MoveHHi(c);         /* DL */
  219.                 HLock(c);           /* DL */
  220.                 b = (CHARH *)*c;    /* DL */
  221.                 for (i=0; i<sizei; i++) {
  222.                     /*low= fgetc(fptr); replace fgetc by fread 1/24/94 */
  223.                                         if(1!=fread(&low,sizeof(char),1,fptr)){
  224.                         sprintf(errbuf,"error: possible EOF found at (%d,%d)\n",j,i); /* TS */
  225.                         errmsg(errbuf,&resnum);  /* TS */
  226.                         break;
  227.                     } else {
  228.                         b[k++]=(unsigned char) low;  /* DL */
  229.                     }
  230.                 HUnlock(c);    /* DL */
  231.                 }
  232.             }
  233.         }
  234.  
  235.         pds.image = c;
  236.         break;
  237.     default:
  238.         errmsg("invalid number of bits per pixel\n",&resnum);  /* TS */
  239.         pds.image = NULL;
  240.     }
  241.  
  242.     /************    Allocate string buffer    **************/
  243.     rewind(fptr);
  244.  
  245.     pds.text = (char *)malloc(hdr_size);
  246.     if ( pds.text ) {
  247.         for (ptr=pds.text,i=0; i<hdr_size; i++) {
  248.                /*    *(ptr) = fgetc(fptr); */
  249.             fread(ptr,sizeof(char),1,fptr);
  250.             if ( *ptr=='\r') {
  251.                 /* do nothing */
  252.             } else {
  253.                 ptr++;
  254.             }
  255.         }
  256.     }
  257.     *(ptr)='\0';
  258.  
  259.         /*****/
  260.     fclose(fptr);
  261.  
  262.     *rows = pds.image_nrows=sizej;
  263.     *cols = pds.image_ncols=sizei;
  264.  
  265.     return &pds;
  266. }
  267.  
  268.  
  269. /******** Routines that deal with compressed images *******/
  270. float   dfac[8] = {
  271. 0.35355339,0.35355339,0.653281482,0.27059805,
  272. 0.449988111,0.254897789,0.300672443,1.281457724
  273. };
  274.  
  275. void init_qt(FILE *fptr)
  276. {
  277.     short   i;
  278.     short   scalef,index;
  279.     short   table[64];
  280.     float   ftable[64];
  281.  
  282.     fread(&scalef,sizeof(short),1,fptr);
  283. #if defined(sun) || defined(__STDC__)
  284.     PCshort2SUNshortVector((unsigned short*)&scalef,1) ;
  285. #endif
  286.     fprintf(qparm,"tabf: %d\n",scalef);
  287.     fread(table,sizeof(short),64,fptr);
  288. #if defined(sun) || defined(__STDC__)
  289.     PCshort2SUNshortVector((unsigned short*)table,64);
  290. #endif
  291.     fprintf(qparm,"tabq:\n");
  292.  
  293.     for (i=0; i<64; i++) {
  294.         fprintf(qparm,"%3d ",table[i]);
  295.         if ( (i+1) % 8 == 0 ) fprintf(qparm,"\n");
  296.  
  297.         ftable[i] = (float)floor((float)scalef*table[i]/64.0 + 0.5);
  298.         ftable[i] = 4096.0 / ftable[i];
  299.     }
  300.  
  301.     ftable[0] = dfac[0]*dfac[0]*ftable[0];
  302.     ftable[32] = dfac[0]*dfac[1]*ftable[32];
  303.     ftable[16] = dfac[0]*dfac[2]*ftable[16];
  304.     ftable[48] = dfac[0]*dfac[3]*ftable[48];
  305.     ftable[8] = -dfac[0]*dfac[4]*ftable[8];
  306.     ftable[24] = -dfac[0]*dfac[5]*ftable[24];
  307.     ftable[56] = dfac[0]*dfac[6]*ftable[56];
  308.     ftable[40] = -dfac[0]*dfac[7]*ftable[40];
  309.  
  310.     ftable[4] = dfac[1]*dfac[0]*ftable[4];
  311.     ftable[36] = dfac[1]*dfac[1]*ftable[36];
  312.     ftable[20] = dfac[1]*dfac[2]*ftable[20];
  313.     ftable[52] = dfac[1]*dfac[3]*ftable[52];
  314.     ftable[12] = -dfac[1]*dfac[4]*ftable[12];
  315.     ftable[28] = -dfac[1]*dfac[5]*ftable[28];
  316.     ftable[60] = dfac[1]*dfac[6]*ftable[60];
  317.     ftable[44] = -dfac[1]*dfac[7]*ftable[44];
  318.  
  319.     ftable[2] = dfac[2]*dfac[0]*ftable[2];
  320.     ftable[34] = dfac[2]*dfac[1]*ftable[34];
  321.     ftable[18] = dfac[2]*dfac[2]*ftable[18];
  322.     ftable[50] = dfac[2]*dfac[3]*ftable[50];
  323.     ftable[10] = -dfac[2]*dfac[4]*ftable[10];
  324.     ftable[26] = -dfac[2]*dfac[5]*ftable[26];
  325.     ftable[58] = dfac[2]*dfac[6]*ftable[58];
  326.     ftable[42] = -dfac[2]*dfac[7]*ftable[42];
  327.  
  328.     ftable[6] = dfac[3]*dfac[0]*ftable[6];
  329.     ftable[38] = dfac[3]*dfac[1]*ftable[38];
  330.     ftable[22] = dfac[3]*dfac[2]*ftable[22];
  331.     ftable[54] = dfac[3]*dfac[3]*ftable[54];
  332.     ftable[14] = -dfac[3]*dfac[4]*ftable[14];
  333.     ftable[30] = -dfac[3]*dfac[5]*ftable[30];
  334.     ftable[62] = dfac[3]*dfac[6]*ftable[62];
  335.     ftable[46] = -dfac[3]*dfac[7]*ftable[46];
  336.  
  337.     ftable[1] = -dfac[4]*dfac[0]*ftable[1];
  338.     ftable[33] = -dfac[4]*dfac[1]*ftable[33];
  339.     ftable[17] = -dfac[4]*dfac[2]*ftable[17];
  340.     ftable[49] = -dfac[4]*dfac[3]*ftable[49];
  341.     ftable[9] = dfac[4]*dfac[4]*ftable[9];
  342.     ftable[25] = dfac[4]*dfac[5]*ftable[25];
  343.     ftable[57] = -dfac[4]*dfac[6]*ftable[57];
  344.     ftable[41] = dfac[4]*dfac[7]*ftable[41];
  345.  
  346.     ftable[3] = -dfac[5]*dfac[0]*ftable[3];
  347.     ftable[35] = -dfac[5]*dfac[1]*ftable[35];
  348.     ftable[19] = -dfac[5]*dfac[2]*ftable[19];
  349.     ftable[51] = -dfac[5]*dfac[3]*ftable[51];
  350.     ftable[11] = dfac[5]*dfac[4]*ftable[11];
  351.     ftable[27] = dfac[5]*dfac[5]*ftable[27];
  352.     ftable[59] = -dfac[5]*dfac[6]*ftable[59];
  353.     ftable[43] = dfac[5]*dfac[7]*ftable[43];
  354.  
  355.     ftable[7] = dfac[6]*dfac[0]*ftable[7];
  356.     ftable[39] = dfac[6]*dfac[1]*ftable[39];
  357.     ftable[23] = dfac[6]*dfac[2]*ftable[23];
  358.     ftable[55] = dfac[6]*dfac[3]*ftable[55];
  359.     ftable[15] = -dfac[6]*dfac[4]*ftable[15];
  360.     ftable[31] = -dfac[6]*dfac[5]*ftable[31];
  361.     ftable[63] = dfac[6]*dfac[6]*ftable[63];
  362.     ftable[47] = -dfac[6]*dfac[7]*ftable[47];
  363.  
  364.     ftable[5] = -dfac[7]*dfac[0]*ftable[5];
  365.     ftable[37] = -dfac[7]*dfac[1]*ftable[37];
  366.     ftable[21] = -dfac[7]*dfac[2]*ftable[21];
  367.     ftable[53] = -dfac[7]*dfac[3]*ftable[53];
  368.     ftable[13] = dfac[7]*dfac[4]*ftable[13];
  369.     ftable[29] = dfac[7]*dfac[5]*ftable[29];
  370.     ftable[61] = -dfac[7]*dfac[6]*ftable[61];
  371.     ftable[45] = dfac[7]*dfac[7]*ftable[45];
  372.  
  373.     for (i=0; i<64; i++) qtable[i] = ftable[zzseq[i]];
  374. }
  375.  
  376. void readhufftbls(FILE *fptr)
  377. {
  378.     fread(dcbits,sizeof(short),16,fptr);
  379. #if defined(sun) || defined(__STDC__)
  380.     PCshort2SUNshortVector((unsigned short*)dcbits,16);
  381. #endif
  382.  
  383.     fread(dchuffval,sizeof(char),12,fptr);
  384.     fread(acbits,sizeof(short),16,fptr);
  385. #if defined(sun) || defined(__STDC__)
  386.     PCshort2SUNshortVector((unsigned short*)acbits,16);
  387. #endif
  388.  
  389.     fread(achuffval,sizeof(char),162,fptr);
  390.  
  391.     inithuffcode();
  392. }
  393.  
  394.  
  395. void pds_decomp(FILE *fptr,CHARH *p,long sizej,long sizei)
  396. {
  397.     BitStream       ibs;
  398.     short   i, npanels;
  399.     long    nbytes,bytesperpanel;
  400.     short   blocks, rem;
  401.     unsigned short  nb;
  402.     long    filepos1, filepos2;
  403.     CHARH   *ptr;
  404.     int     FLAG = 0;
  405.  
  406.     cBitStream(&ibs,NULL,INPUT);
  407.  
  408.     filepos1 = ftell(fptr);
  409.     fseek(fptr,0,2);
  410.     filepos2 = ftell(fptr);
  411.     fseek(fptr,filepos1,0);
  412.  
  413.     nbytes = filepos2 - filepos1;
  414.  
  415. #ifdef __TURBOC__
  416.     ibs.outstring = (CHARH *)farmalloc(nbytes);
  417. #else
  418.     ibs.outstring = (CHARH *)malloc(nbytes);
  419. #endif
  420.     if ( ibs.outstring ) {
  421.         blocks = 1;
  422.         rem = 0;
  423.         nb = (unsigned short)nbytes;
  424.         if ( nbytes > 60000L ) {
  425.             blocks = nbytes / 32768;
  426.             rem = nbytes % 32768;
  427.             nb = 32768;
  428.         };
  429.         ptr = ibs.outstring;
  430.         for (i=0; i < blocks; i++,ptr+=nb) {
  431.             if ( fread(ptr,sizeof(char),nb,fptr) != nb ) {
  432.                 errmsg("Error reading data string.\n",&resnum);  /* TS */
  433.                 FLAG = 1;
  434.                 break;
  435.             }
  436.         }
  437.         if ( rem ) {
  438.             if ( fread(ptr,sizeof(char),rem,fptr) != rem ) {
  439.                 errmsg("Error reading data string.\n",&resnum);  /* TS */
  440.                 FLAG = 1;
  441.             }
  442.         }
  443.         ibs.mode = MEMORY;
  444.     } else {
  445.         ibs.bytestream.file = fptr;
  446.         ibs.mode = DISK;
  447.     }
  448.  
  449.     if ( !FLAG ) {
  450.         npanels = sizej/32;
  451.         bytesperpanel = 32*sizei;
  452.         for (i=0; i<npanels; i++,p+=bytesperpanel) {
  453.             decomp(&ibs,p,32,sizei);
  454.         }
  455.     }
  456.  
  457.     if ( ibs.outstring )
  458. #ifdef __TURBOC__
  459.         farfree( ibs.outstring );
  460. #else
  461.         free( ibs.outstring );
  462. #endif
  463. }
  464.  
  465.  
  466. #if defined(sun) || defined(__STDC__)
  467. void PClong2SUNlongVector(unsigned long invec[],int npts){
  468.     int    i;
  469.     unsigned long     ival,oval;
  470.  
  471.     for(i=0;i<npts;i++){
  472.         ival    = invec[i];
  473.         oval    = ((ival&0x000000ff)<<24) +
  474.               ((ival&0x0000ff00)<<8) +
  475.               ((ival&0x00ff0000)>>8) +
  476.               ((ival&0xff000000)>>24);
  477.         invec[i]= oval; 
  478.     }
  479. }
  480. void PCshort2SUNshortVector(unsigned short invec[],int npts){
  481.     int    i;
  482.         unsigned short     ival,oval;
  483.      for(i=0;i<npts;i++){
  484.         ival    = invec[i];
  485.         oval    = (ival<<8) + ((ival>>8)&0x00ff);
  486.         invec[i]= oval;
  487.  
  488.         }
  489. }
  490. #endif
  491.  
  492.